package com.example.dailyrecord.config;

import com.alibaba.fastjson.JSON;
import com.example.dailyrecord.base.entity.ResultMsg;
import com.example.dailyrecord.entity.StatusCode;
import com.example.dailyrecord.entity.Token;
import com.example.dailyrecord.util.RequestUtils;
import com.example.dailyrecord.util.TokenUtils;
import lombok.Data;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

@Data
@Component
@ConfigurationProperties(prefix = "auth.whitelist")
public class TokenFilter extends OncePerRequestFilter {
    @Resource
    TokenUtils tokenUtils;
    private String[] uris;
    private String[] formatter;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        if (isWhiteList(request) || "OPTIONS".equals(request.getMethod())) {
            String requestURI = request.getRequestURI();
            if (requestURI.contains("static/static")) {
                response.sendRedirect(requestURI.replace("static/static", "static"));
            } else {
                filterChain.doFilter(request, response);
            }
        } else {
            String content = RequestUtils.getToken(request);
            Token token = tokenUtils.parse(content);
            if (token.useful()) {
                filterChain.doFilter(request, response);
            } else {
                ServletOutputStream outputStream = response.getOutputStream();
                String res = JSON.toJSONString(ResultMsg.getInstance(StatusCode.TOKEN_INVALID));
                outputStream.write(res.getBytes(StandardCharsets.UTF_8));
                outputStream.flush();
                outputStream.close();
            }
        }
    }


    private boolean isWhiteList(HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        boolean contains = ArrayUtils.contains(uris, requestURI);
        if (contains) {
            return true;
        } else {
            return StringUtils.endsWithAny(requestURI, formatter);
        }
    }
}

